package edu.bu.grocery.backingbean;

import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import edu.bu.grocery.session.UserSession;
import edu.bu.grocerylist.model.GroceryList;
import edu.bu.grocerylist.model.GroceryListItem;
import edu.bu.grocerylist.service.IGroceryListService;

/**
 * This BackingBean is used to represent and interact with the GroceryList edit page.  On
 * this page, we edit existing, modify new ones, or modify templated GroceryList objects
 * @author donlanp
 *
 */
public class GroceryListBackingBean implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -2792382176877369972L;

	private UserSession session;
	
	private IGroceryListService listService;

	private GroceryListItem itemToAdd;
	private String title;
	
	/**
	 * Initializes variables
	 */
	@PostConstruct
	public void init(){
		itemToAdd = new GroceryListItem();
	}
	/**
	 * Saves the list currently stored list
	 * @return
	 */
	public String saveList(){
		
		
		// Validate fields
		
		// name
		if (session.getCurrentGroceryList().getName() == null || session.getCurrentGroceryList().getName().equals("") ) {
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("A grocerylist name must be entered"));
			return "";
		}
		
		// date
		if (session.getCurrentGroceryList().getShoppingDate() == null) {
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Date must be in valid form (e.g. mm/dd/yyyy)"));
			return "";
		}

		GroceryList groceryList = session.getCurrentGroceryList();
		groceryList.setGroceryUserId(session.getCurrentUser().getUserId());
		session.setCurrentGroceryList(groceryList);
		listService.saveGroceryList(groceryList);
		session.setCurrentGroceryList(null);
		return "grocerylists";
	}
	
	/**
	 * Delete the list in context
	 * @return
	 */
	public String deleteList() {
		listService.deleteGroceryList(session.getCurrentGroceryList());
		return "groceryLists";
	}
	
	/**
	 * Cancels the operation to create a grocery list
	 * @return
	 */
	public String cancel(){
		return "grocerylists";
	}
	
	/**
	 * Adds the item to our currentGroceryList
	 */
	public String addItemToList(){
		System.err.println("Attempt to add item to list (save)");
		List<GroceryListItem> grocerylistitems = session.getCurrentGroceryList().getShoppingItems();
		//List<GroceryListItem> grocerylistitems = groceryList.getShoppingItems();
		
		// search if grocery list item exists. if it does, remove it. The item will be replaced
		for (GroceryListItem item: grocerylistitems) {
			if (item.getName().equals(itemToAdd.getName())) {
				grocerylistitems.remove(item);
				break;
			}
		}
		grocerylistitems.add(itemToAdd);
		GroceryList groceryList = session.getCurrentGroceryList();
		groceryList.setShoppingItems(grocerylistitems);
		session.setCurrentGroceryList(groceryList);
		itemToAdd = new GroceryListItem();
		return "grocerylist";
	}
	
	/**
	 * navigate to grocery list add item screen to populate item and essentially add it to the list
	 * @return
	 */
	public String prepareItemForAdd() {
		GroceryListItem item = new GroceryListItem();
		itemToAdd = item;
		return "grocerylistadditem";
	}
	
	/**
	 * Creates a template and stores it in the session for creation of a new GroceryList
	 * @param groceryList The GroceryList object we're templating off of
	 * @return JSF Navigation string to grocerylist page
	 */
	public String templateGroceryList(GroceryList groceryList) {
		session.setCurrentGroceryList(listService.templateGroceryList(groceryList));
		return "grocerylist";
	}
	
	/**
	 * Called when we're editing an existing grocerylist for storing it temporarily in the session and 
	 * moving to the groceryList edit page
	 * @param grocerylistid The id of the grocerylist we're editing
	 * @return JSF Navigation string to the grocerylist page
	 */
	public String editGroceryList(int grocerylistid) {
		GroceryList groceryList = listService.getGroceryListById(grocerylistid);
		session.setCurrentGroceryList(groceryList);
		return "grocerylist";
	}
	
	
	/**
	 * Obtains the list of items from the currently stored GroceryList object
	 * @return The List of grocery items
	 */
	public List<String> getAvailableItems() {
		List<String> itemnames = new LinkedList<String>();
		
		for (GroceryListItem name: this.session.getCurrentGroceryList().getShoppingItems()) {
			itemnames.add(name.getName());
		}
		return itemnames;
	}
	
	
	public String editItemFromGroceryList() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		String listitemName = facesContext.getExternalContext().getRequestParameterMap().get("groceryListItemName");
		GroceryListItem itemtoedit = null;
		// get the grocery item with the matching name, quantity, measurement.
		for (GroceryListItem item: this.session.getCurrentGroceryList().getShoppingItems()) {
			// got the item
			if (item.getName().equals(listitemName)) {
				itemtoedit = item;
				break;
			}
		}
		
		// error condition
		if (itemtoedit == null) {
			System.err.println("Unable to find item. No-op");
			return "";
		}
		
		System.err.println("Item to edit is" + itemtoedit);
		itemToAdd = itemtoedit;
		return "grocerylistadditem";
	}
	
	/**
	 * Deletes the selected item from the list, we pass in the item id for the grocerylist, and from there we can delete the item
	 * @return JSF navigation string, used to "refresh" the page
	 */
	public String deleteItemFromGroceryList() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		String listitemToDelete = facesContext.getExternalContext().getRequestParameterMap().get("groceryListItem");
		GroceryList grocerylist = session.getCurrentGroceryList();
		List<GroceryListItem> grocerylistitems = grocerylist.getShoppingItems();
		System.err.println("Deleting item from grocery list...");
		GroceryListItem deleteitem = null;
		for (GroceryListItem item: grocerylistitems) {
			if (item.getName().equals(listitemToDelete)) {
				deleteitem = item;
				break;
			}
		}
		
		if (deleteitem != null) {
			grocerylistitems.remove(deleteitem);
			grocerylist.setShoppingItems(grocerylistitems);
			session.setCurrentGroceryList(grocerylist);
		}
		else {
			System.err.println("Nothing to delete!");
		}
		
		return "grocerylist";
	}
	
	/**
	 * Sorts the items by category
	 * @return
	 */
	public List<GroceryListItem> getSortedItems(){
		List<GroceryListItem> items = getGroceryList().getShoppingItems();
		
		Collections.sort(items);
		
		return items;
	}
	
	//Getters and Setters
	
	
	public boolean getIsListEmpty(){
		return getAvailableItems().isEmpty();
	}
	


	/**
	 * @return the session
	 */
	public UserSession getSession() {
		return session;
	}

	/**
	 * @param session the session to set
	 */
	public void setSession(UserSession session) {
		this.session = session;
	}

	/**
	 * @return the listService
	 */
	public IGroceryListService getListService() {
		return listService;
	}

	/**
	 * @param listService the listService to set
	 */
	public void setListService(IGroceryListService listService) {
		this.listService = listService;
	}

	/**
	 * @return the groceryList
	 */
	public GroceryList getGroceryList() {
		return session.getCurrentGroceryList();
	}

	/**
	 * @param groceryList the groceryList to set
	 */
	public void setGroceryList(GroceryList groceryList) {
		session.setCurrentGroceryList(groceryList);
	}
	

	
	/**
	 * @return the title 
	 */
	public String getTitle() {
		return title;
	}
	
	public GroceryListItem getItemToAdd() {
		return itemToAdd;
	}
	
	public void setItemToAdd(GroceryListItem item) {
		this.itemToAdd = item;
	}
	
	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}
	
}
